package services.common;

import java.math.BigDecimal;
import java.security.InvalidParameterException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import play.mvc.Http.Request;

import com.alibaba.fastjson.JSONObject;
import com.shove.Convert;
import com.shove.security.Encrypt;
import com.zhongan.scorpoin.common.ZhongAnOpenException;

import common.constants.CacheKey;
import common.constants.ConfConst;
import common.constants.SettingKey;
import common.enums.Client;
import common.enums.CompanyInfoType;
import common.enums.IsCompany;
import common.enums.NoticeScene;
import common.enums.ServiceType;
import common.utils.DateUtil;
import common.utils.Factory;
import common.utils.LoggerUtil;
import common.utils.OrderNoUtil;
import common.utils.PageBean;
import common.utils.ReentrantLockUtil;
import common.utils.ResultInfo;
import common.utils.number.Arith;
import daos.common.UserFundDao;
import daos.common.UserInfoDao;
import models.common.entity.t_company_info;
import models.common.entity.t_deal_platform;
import models.common.entity.t_deal_user;
import models.common.entity.t_deal_user.OperationType;
import models.common.entity.t_finance_record;
import models.common.entity.t_finance_record.IsPayment;
import models.common.entity.t_event_user;
import models.common.entity.t_recharge_user;
import models.common.entity.t_user;
import models.common.entity.t_user_fund;
import models.common.entity.t_user_info;
import models.common.entity.t_withdrawal_user;
import services.base.BaseService;

public class UserFundService extends BaseService<t_user_fund> {
	
	protected static UserInfoDao userInfoDao = Factory.getDao(UserInfoDao.class);
	
	protected static UserFundDao userFundDao = Factory.getDao(UserFundDao.class);
	
	protected static RechargeUserService rechargeUserService = Factory.getService(RechargeUserService.class);
	
	protected static WithdrawalUserService withdrawalUserService = Factory.getService(WithdrawalUserService.class);
	
	protected static UserService userService = Factory.getService(UserService.class);
	
	
	protected static UserInfoService userInfoService = Factory.getService(UserInfoService.class);
	
	protected static DealUserService dealUserService = Factory.getService(DealUserService.class);
	
	protected static NoticeService noticeService = Factory.getService(NoticeService.class);
	
	protected static SettingService settingService = Factory.getService(SettingService.class);
	
	protected static BankCardUserService bankCardUserService = Factory.getService(BankCardUserService.class);
	
	protected static DealPlatformService dealPlatformService = Factory.getService(DealPlatformService.class);
	
	protected static CompanyInfoService companyInfoService = Factory.getService(CompanyInfoService.class);
	
	protected static FinanceRecordService financeRecordService = Factory.getService(FinanceRecordService.class);
	
	
	protected UserFundService(){
		super.basedao = userFundDao;
	}
	
	@Override
	public t_user_fund findByID(long id) {
		//禁用此方法
		throw new RuntimeException("UserFundService中的findByID()禁止使用 ");

	}
	
	/**
	 * 添加用户资金信息
	 * 
	 * @param userId 用户id
	 * @param name 用户名
	 * @return
	 *
	 * @author liaijun
	 * @createDate 2015年12月19日
	 */
	public boolean addUserFundInfo(long userId, String name) {
		t_user_fund userFund = new t_user_fund();
		userFund.user_id = userId;
		userFund.name = name;
		userFund.payment_account = "";
		userFund.fund_sign = "";
		
		return userFundDao.save(userFund);
	}
	
	/**
	 * 资金托管开户（执行）
	 *
	 * @param userId
	 * @param paymentAccount
	 * @param realName
	 * @param idNumber
	 * @param mobile
	 * @param email
	 * @return
	 *
	 * @author huangyunsong
	 * @createDate 2016年1月8日
	 */
	public ResultInfo doCreateAccount(long userId, String paymentAccount,
			String realName, String idNumber, String email) {
		ResultInfo result = new ResultInfo();
		
		//保存托管账户
		int row = userFundDao.updatePaymentAccount(userId, paymentAccount);
		if (row < 1) {
			result.code = -1;
			result.msg = "保存第三方托管账户失败";
			
			return result;
		}
		
		t_user user = userService.findByID(userId);
		
		String user_name = user.name;
		if (user.is_company == user.getIsCompany().IS_PERSON.code) {
			t_user_info userInfo = userInfoService.findUserInfoByUserId(userId);
			if (userInfo == null) {
				result.code = -1;
				result.msg = "查询用户信息失败";
				
				return result;
			}
			
			if (StringUtils.isNotBlank(realName)) {
				userInfo.reality_name = realName;
			}
			
			if (StringUtils.isNotBlank(idNumber)) {
				userInfo.id_number = idNumber;
			}
			
			if (StringUtils.isNotBlank(email)) {
				userInfo.email = email;
			}
			result = userInfoService.updateUserInfo(userInfo);
			if (result.code < 0) {
				result.code = -1;
				
				return result;
			}
		}else {
			t_company_info company_info = companyInfoService.findCompanyInfoByUserId(userId);
			if (company_info == null) {
				result.code = -1;
				result.msg = "查询用户信息失败";
				return result;
			}
		}
		/** 发送通知  */
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_name",user_name);
		noticeService.sendSysNotice(userId, NoticeScene.ACCOUTN_OPENING_SUCC, param);
		
		//刷新用户缓存信息
		userService.flushUserCache(userId);
		
		result.code = 1;
		result.msg = "开户成功";
		
		return result;
	}
	
	/**
	 * 用户充值（准备）
	 *
	 * @param userId 用户ID
	 * @param serviceOrderNo 业务订单号
	 * @param rechargeAmt 充值金额
	 * @param summary 备注
	 * @param 登录端
	 * @param 上传的凭证
	 * @return
	 *
	 * @author liaijun
	 * @createDate 2017/04/20
	 */
	public ResultInfo recharge(long userId, String serviceOrderNo, double rechargeAmt, String summary,Client client,String imageUrls) {
		ResultInfo result = new ResultInfo();
		
		//用户资金签名校验
		result = this.userFundSignCheck(userId);
		if (result.code < 1) {
			
			return result;
		}
		
		//最低充值金额
		String minRechargeAmtStr = settingService.findSettingValueByKey(SettingKey.RECHARGE_AMOUNT_MIN);
		double minRechargeAmt = Convert.strToDouble(minRechargeAmtStr, 100);
		if (rechargeAmt < minRechargeAmt) {
			result.code = -1;
			result.msg = "充值不能低于"+minRechargeAmt+"元";
			
			return result;
		}
		
		//最高充值金额
		/*String maxRechargeAmtStr = settingService.findSettingValueByKey(SettingKey.RECHARGE_AMOUNT_MAX);
		double maxRechargeAmt = Convert.strToDouble(maxRechargeAmtStr, 100);
		if (rechargeAmt > maxRechargeAmt) {
			result.code = -1;
			result.msg = "充值不能高于"+maxRechargeAmt+"元";
			
			return result;
		}*/
		
		//添加充值记录
		boolean isAdd = rechargeUserService.addUserRecharge(userId, serviceOrderNo, rechargeAmt, summary,client,imageUrls);
		if (!isAdd) {
			result.code = -1;
			result.msg = "添加充值记录失败";
			
			return result;
		}
		
		result.code = 1;
		result.msg = "充值准备完毕";
		
		return result;
	}

	/**
	 * 用户充值（执行）
	 *
	 * @param userId 用户ID
	 * @param rechargeAmt 充值金额
	 * @param serviceOrderNo 业务订单号
	 * @return
	 *
	 * @author huangyunsong
	 * @createDate 2016年1月8日
	 */
	public ResultInfo doRecharge(long userId, double rechargeAmt, String serviceOrderNo) {
		ResultInfo result = new ResultInfo();

		int row = rechargeUserService.updateRechargeToSuccess(serviceOrderNo);
		
		if (row < 1) {
			result.code = -1;
			result.msg = "更新充值记录失败";
			
			return result;
		}

		boolean isAdd = userFundAdd(userId, rechargeAmt);
		if (!isAdd) {
			result.code = -1;
			result.msg = "增加用户可用余额失败";
			
			return result;
		}
		
		result = userFundSignUpdate(userId);
		if (result.code < 1) {
			result.code = -1;
			result.msg = "更新用户签名失败";
			
			return result;
		}
		
		t_user_fund userFund = queryUserFundByUserId(userId);
		if (userFund == null) {
			result.code = -1;
			result.msg = "查询用户资金信息失败";
			
			return result;
		}
	    //充值交易记录
		boolean addDeal = dealUserService.addDealUserInfo(
				serviceOrderNo,
				userId,
				rechargeAmt,
				userFund.balance,
				userFund.freeze,
				t_deal_user.OperationType.RECHARGE,
				null);
		
		if (!addDeal) {
			result.code = -1;
			result.msg = "添加充值交易记录失败";
			
			return result;
		}
		
		/** 发送通知 */
		Map<String, Object> sceneParame = new HashMap<String, Object>();
		sceneParame.put("user_name", userFund.name);
		sceneParame.put("amount", rechargeAmt);
		sceneParame.put("balance", userFund.balance);
		noticeService.sendSysNotice(userId, NoticeScene.RECHARGE_SUCC, sceneParame);
		
		result.code = 1;
		result.msg = "该企业充值申请审核成功";

		return result;
	}
	
	/**
	 * 用户绑卡（执行）
	 *
	 * @param userId 用户ID
	 * @param bankName 银行名称
	 * @param bankCode 银行代号
	 * @param account 银行账户
	 * @return
	 *
	 * @author huangyunsong
	 * @createDate 2016年1月9日
	 */
	public ResultInfo doBindCard(long userId, String  bankName, String bankCode, String account) {
		ResultInfo result = new ResultInfo();
		
		boolean isAdd = bankCardUserService.addUserCard(userId, bankName, bankCode, account,null,null,null,null,null);
		if (!isAdd) {
			result.code = -1;
			result.msg = "添加银行卡失败";
			
			return result;
		}
		
		result.code = 1;
		result.msg = "用户绑卡成功";
		/* 刷新当前用户缓存 */
		userService.flushUserCache(userId);
		
		t_user user=userService.findByID(userId);
		/** 发送通知 */
		Map<String, Object> param = new HashMap<String, Object>();
		if (user.is_company==IsCompany.IS_PERSON.code){//个人用户
			t_user_info userInfo = userInfoDao.findByID(userId);
			param.put("user_name", userInfo.name);
		}
		else{
			t_company_info companyInfo = companyInfoService.findByID(userId);
			param.put("user_name", companyInfo.full_name);
		}
		noticeService.sendSysNotice(userId, NoticeScene.ADD_BANKCARD_SUCC, param);
		
		return result;
	}
	
	/**
	 * 提现（准备）
	 *
	 * @return ResultInfo
	 * @author liaijun
	 * @createDate 2017年4月15日
	 */
	public ResultInfo withdrawal(long userId, String serviceOrderNo, double withdrawalAmt, String bankAccount, Client client) {
		ResultInfo result = new ResultInfo();

		t_user_fund userFund = this.queryUserFundByUserId(userId);
		if (userFund == null) {
			result.code = -1;
			result.msg = "查询用户资金信息失败";
			
			return result;
		}
		/*if(withdrawalAmt > 200000){
			result.code = -1;
			result.msg = "不能超过最高提现金额";
			return result;
		}*/
		//用户资金签名校验
		result = this.userFundSignCheck(userId);
		if (result.code < 1) {
			
			return result;
		}
		
		if (userFund.balance < withdrawalAmt) {
			result.code = -1;
			result.msg = "提现余额不足";
			
			return result;
		}
		
		//添加提现记录
		boolean isAdd = withdrawalUserService.addUserWithdrawal(userId, serviceOrderNo, withdrawalAmt, bankAccount, "用户提现", client);
		if (!isAdd) {
			result.code = -1;
			result.msg = "添加提现记录失败";
			
			return result;
		}
		
		result.code = 1;
		result.msg = "提现准备完毕";
		
		return result;
	}

	/**
	 * 用户提现（执行）
	 *
	 * @param userId 关联用户ID
	 * @param withdrawalAmt 提现金额
	 * @param userPayWithdrawalFee 用户支付提现手续费
	 * @param merIncomeWithdrawalFee 平台收取用户提现手续费
	 * @param serviceOrderNo 业务订单号
	 * @param chargeMode 手续费扣除模式：false-内扣；true-外扣
	 * @param serviceMode 业务模式  false-非托管模式, true-托管模式
	 * @return
	 *
	 * @author liaijun
	 * @param merIncomeWithdrawalFee 
	 * @param summary 
	 * @createDate 2017/04/20
	 */
	public ResultInfo doWithdrawal(long userId, double withdrawalAmt, double userPayWithdrawalFee, double merIncomeWithdrawalFee, String serviceOrderNo, boolean chargeMode, boolean serviceMode, String summary) {
		ResultInfo result = new ResultInfo();

		int row = withdrawalUserService.updateWithdrawalToSuccess(serviceOrderNo,summary);
		
		if (row < 1) {
			result.code = -1;
			result.msg = "更新提现记录失败";
			
			return result;
		}
		
		

		boolean isMinus = true;
		
		if(serviceMode){
			
			/*isMinus = userFundMinus(userId, withdrawalAmt);
			if (!isMinus) {
				result.code = -1;
				result.msg = "扣除用户可用余额失败";
				
				return result;
			}*/
			isMinus = userFundMinusFreezeAmt(userId, withdrawalAmt);
			if (!isMinus) {
				result.code = -1;
				result.msg = "扣除用户冻结资金失败";
				
				return result;
			}
		}else{
			
			isMinus = userFundMinusFreezeAmt(userId, withdrawalAmt);
			if (!isMinus) {
				result.code = -1;
				result.msg = "扣除用户冻结资金失败";
				
				return result;
			}
		}
		
		
		result = userFundSignUpdate(userId);
		if (result.code < 1) {
			result.code = -1;
			result.msg = "更新用户签名失败";
			
			return result;
		}
		
		t_user_fund userFund = queryUserFundByUserId(userId);
		if (userFund == null) {
			result.code = -1;
			result.msg = "查询用户资金信息失败";
			
			return result;
		}
		
		//提现交易记录
		double realAmt = withdrawalAmt - userPayWithdrawalFee;
		boolean addDeal = dealUserService.addDealUserInfo(
				serviceOrderNo, 
				userId,
				realAmt,  //实际到账
				userFund.balance ,  //剩下可用余额
				userFund.freeze, 
				t_deal_user.OperationType.WITHDRAW,
				null);
		
		if (!addDeal) {
			result.code = -1;
			result.msg = "添加提现交易记录失败";
			
			return result;
		}
		//提现手续费扣除记录
		addDeal = dealUserService.addDealUserInfo(
				serviceOrderNo, 
				userId,
				userPayWithdrawalFee,
				userFund.balance,
				userFund.freeze, 
				t_deal_user.OperationType.WITHDRAW_FEE,
				null);
		
		if (!addDeal) {
			result.code = -1;
			result.msg = "添加提现手续费扣除记录失败";
			
			return result;
		}
		
		//添加平台收支记录
		String company_name="";
		t_company_info companyEarnings = companyInfoService.findByColumn(" company_type_id = ?" , (long)CompanyInfoType.EARNINGS_ACCOUNT.code );
		if(companyEarnings !=null){
			company_name = companyEarnings.full_name;
		}
		/*addDeal = dealPlatformService.addPlatformDeal(
				userId,
				merIncomeWithdrawalFee, 
				t_deal_platform.DealRemark.WITHDRAW_FREE_INCOME,
				null,0,0,company_name);
			if (!addDeal) {
			result.code = -1;
			result.msg = "添加平台收支记录失败";
			
			return result;
		}*/
		
		/** 发送通知 */
		Map<String, Object> sceneParame = new HashMap<String, Object>();
		sceneParame.put("user_name", userFund.name);
		sceneParame.put("withdraw_amount", withdrawalAmt);
		//sceneParame.put("fee", userPayWithdrawalFee);
		sceneParame.put("actual_amount", realAmt);
		sceneParame.put("balance", userFund.balance);
		noticeService.sendSysNotice(userId, NoticeScene.WITHDRAW_SUCC, sceneParame);
		
		result.code = 1;
		result.msg = "提现成功";

		return result;
	}
	
	/**
	 * 冻结用户提现
	 *
	 * @param userId 关联用户ID
	 * @param withdrawalAmt 提现金额
	 * @param serviceOrderNo 业务订单号
	 * @return
	 *
	 * @author huangyunsong
	 * @createDate 2016年1月11日
	 */
	public ResultInfo freezeWithdrawal(long userId, double withdrawalAmt, String serviceOrderNo) {
		ResultInfo result = new ResultInfo();
		
		int row = withdrawalUserService.updateWithdrawalToFreeze(serviceOrderNo);
		
		if (row < 1) {
			result.code = -1;
			result.msg = "更新提现记录失败";
			
			return result;
		}
		
		boolean isMinus = userFundFreeze(userId, withdrawalAmt);
		if (!isMinus) {
			result.code = -1;
			result.msg = "冻结用户可用余额失败";
			
			return result;
		}
		
		result = userFundSignUpdate(userId);
		if (result.code < 1) {
			result.code = -1;
			result.msg = "更新用户签名失败";
			
			return result;
		}
		
		t_user_fund userFund = queryUserFundByUserId(userId);
		if (userFund == null) {
			result.code = -1;
			result.msg = "查询用户资金信息失败";
			
			return result;
		}
		boolean addDeal = dealUserService.addDealUserInfo(
				serviceOrderNo, 
				userId,
				withdrawalAmt,
				userFund.balance,
				userFund.freeze, 
				t_deal_user.OperationType.WITHDRAW_FREEZE,
				null);
		
		if (!addDeal) {
			result.code = -1;
			result.msg = "添加提现交易记录失败";
			
			return result;
		}
		
		result.code = 1;
		result.msg = "提现申请成功";

		return result;
	}
	
	/**
	 * 提现审核不通过(原银行支付接口)
	 * @param withdrawalId
	 * @param summary 
	 * @return
	 */
	public ResultInfo auditWithdrawalFail(long withdrawalId) {
		ResultInfo result = new ResultInfo();
		
		int row = withdrawalUserService.auditWithdrawalFail(withdrawalId);
		
		if (row < 1) {
			result.code = -1;
			result.msg = "更新提现记录失败";
			
			return result;
		}
		
		t_withdrawal_user wu = t_withdrawal_user.findById(withdrawalId);
		long userId = wu.user_id;

		boolean isMinus = userFundUnFreeze(userId, wu.amount);
		if (!isMinus) {
			result.code = -1;
			result.msg = "解冻用户冻结资金失败";
			
			return result;
		}
		
		result = userFundSignUpdate(userId);
		if (result.code < 1) {
			result.code = -1;
			result.msg = "更新用户签名失败";
			
			return result;
		}
		
		t_user_fund userFund = queryUserFundByUserId(userId);
		if (userFund == null) {
			result.code = -1;
			result.msg = "查询用户资金信息失败";
			
			return result;
		}
		boolean addDeal = dealUserService.addDealUserInfo(
				wu.order_no, 
				userId,
				wu.amount,
				userFund.balance,
				userFund.freeze, 
				t_deal_user.OperationType.WITHDRAW_UNFREEZE,
				null);
		
		if (!addDeal) {
			result.code = -1;
			result.msg = "添加提现交易记录失败";
			
			return result;
		}
		
		result.code = 1;
		result.msg = "提现审核不通过成功";

		return result;
	}
	
	/**
	 * 审核提现申请不通过（新定义）
	 *
	 * @param withdrawalId 提现申请
	 * @param summary 理由
	 * @return
	 * @author LiangQiongfeng
	 *@version 2018-1-17
	 */
	public ResultInfo auditWithdrawalFail2(long withdrawalId, String summary) {
		ResultInfo result = new ResultInfo();
		
		int row = withdrawalUserService.auditWithdrawalFail2(withdrawalId,summary);
		
		if (row < 1) {
			result.code = -1;
			result.msg = "更新提现记录失败";
			
			return result;
		}
		
		t_withdrawal_user wu = t_withdrawal_user.findById(withdrawalId);
		long userId = wu.user_id;
		
		boolean isMinus = userFundUnFreeze(userId, wu.amount);
		if (!isMinus) {
			result.code = -1;
			result.msg = "解冻用户冻结资金失败";
			
			return result;
		}
		
		result = userFundSignUpdate(userId);
		if (result.code < 1) {
			result.code = -1;
			result.msg = "更新用户签名失败";
			
			return result;
		}
		
		t_user_fund userFund = queryUserFundByUserId(userId);
		if (userFund == null) {
			result.code = -1;
			result.msg = "查询用户资金信息失败";
			
			return result;
		}
		boolean addDeal = dealUserService.addDealUserInfo(
				wu.order_no, 
				userId,
				wu.amount,
				userFund.balance,
				userFund.freeze, 
				t_deal_user.OperationType.WITHDRAW_UNFREEZE,
				null);
		
		if (!addDeal) {
			result.code = -1;
			result.msg = "添加提现交易记录失败";
			
			return result;
		}
		t_withdrawal_user withdrawal_user = withdrawalUserService.findByID(withdrawalId);
		//发送信息
		Map<String,Object> sceneParame = new HashMap<String,Object>();
		t_user user = userService.findByID(userId);
		sceneParame.put("user_name", user.company_full_name);
		sceneParame.put("withdraw_amount", withdrawal_user.amount);
		sceneParame.put("summary", summary);
		noticeService.sendSysNotice(userId, NoticeScene.WITHDRAW_AUDIT_FAIL, sceneParame);
		result.code = 1;
		result.msg = "提现审核不通过成功";
		
		return result;
	}
	
	/**
	 * 增加用户可用余额
	 * 		注意：amount必须大于0，否则抛出异常
	 * 
	 * @param userId 用户id 
	 * @param amount 变动金额
	 * @return
	 *
	 * @author liaijun
	 * @createDate 2015年12月19日
	 */
	public boolean userFundAdd(long userId, double amount) {
		if (amount < 0) {
			
			throw new InvalidParameterException("amount < 0");
		}
		
		int row = userFundDao.updateUserFundAdd(userId, amount);
		
		if (row < 1) {
			LoggerUtil.info(true, "增加用户可用余额失败，【userId：%s，amount：%s】", userId, amount);

			return false;
		}

		return true;
	}

	/**
	 * 扣除用户可用余额
	 * 	注意：amount必须大于0，否则抛出异常
	 * 
	 * @param userId 用户id
	 * @param amount 变动金额
	 * @return
	 *
	 * @author liaijun
	 * @createDate 2015年12月19日
	 */
	public boolean userFundMinus(long userId, double amount) {
		if (amount <= 0) {
			
			throw new InvalidParameterException("amount <= 0");
		}
		
		int row = userFundDao.updateUserFundMinus(userId, amount);
		
		if (row < 1) {
			LoggerUtil.info(true, "扣除用户虚拟资产失败，【userId：%s，amount：%s】", userId, amount);
			
			return false;
		}
		
		return true;
	}

	/**
	 * 扣除用户冻结金额
	 *     注意：amount必须大于0，否则抛出异常
	 * 
	 * @param userId 用户id
	 * @param amount 变动金额
	 * @return
	 *
	 * @author liaijun
	 * @createDate 2015年12月19日
	 */
	public boolean userFundMinusFreezeAmt(long userId, double amount) {
		if (amount < 0) {
			
			throw new InvalidParameterException("amount < 0");
		}
		
		int row = userFundDao.updateUserFundMinusFreezeAmt(userId, amount);
		
		if (row < 1) {
			LoggerUtil.info(true, "扣除用户冻结金额失败，【userId：%s，amount：%s】", userId, amount);
			
			return false;
		}
		userFundSignUpdate(userId);
		return true;
	}

	/**
	 * 冻结用户资金
	 * 		注意：amount必须大于0，否则抛出异常
	 * 
	 * @param userId 用户id
	 * @param amount 变动金额
	 * @return
	 *
	 * @author liaijun
	 * @createDate 2015年12月19日
	 */
	public boolean userFundFreeze(long userId, double amount) {
		if (amount < 0) {
			
			throw new InvalidParameterException("amount < 0");
		}
		
		int row = userFundDao.updateUserFundFreeze(userId, amount);
		
		if (row < 1) {
			LoggerUtil.info(true, "冻结用户资金失败，【userId：%s，amount：%s】", userId, amount);
			
			return false;
		}
		ResultInfo result = userFundSignUpdate(userId);
		if(result.code <0){
			return false;
		}
		return true;
	}

	/**
	 * 解冻用户冻结资金
	 * 	注意：amount必须大于0，否则抛出异常
	 * 
	 * @param userId 用户id
	 * @param amount 变动金额
	 * @return
	 *
	 * @author liaijun
	 * @createDate 2015年12月19日
	 */
	public boolean userFundUnFreeze(long userId, double amount) {
		if (amount < 0) {
			
			throw new InvalidParameterException("amount < 0");
		}
		
		int row = userFundDao.updateUserFundUnFreeze(userId, amount);
		
		if (row < 1) {
			LoggerUtil.info(true, "解冻用户冻结资金失败，【userId：%s，amount：%s】", userId, amount);
			
			return false;
		}
		
		return true;
	}
	
	/**
	 * 增加用户的虚拟资产
	 *
	 * @param userId
	 * @param amount
	 * @return
	 *
	 * @author DaiZhengmiao
	 * @createDate 2016年2月16日
	 */
	public boolean userVisualFundAdd(long userId,double amount){
		if (amount <= 0) {
			
			throw new InvalidParameterException("amount <= 0");
		}
		
		int row = userFundDao.updateUserVisualFundAdd(userId, amount);
		
		if (row < 1) {
			LoggerUtil.info(true, "增加用户虚拟资产失败，【userId：%s，amount：%s】", userId, amount);

			return false;
		}

		return true;
	}
	
	/**
	 * 扣除用户的虚拟资产
	 *
	 * @param userId
	 * @param amount
	 * @return
	 *
	 * @author DaiZhengmiao
	 * @createDate 2016年2月16日
	 */
	public boolean userVisualFundMinus(long userId,double amount){
		if (amount <= 0) {
			
			throw new InvalidParameterException("amount <= 0");
		}
		
		int row = userFundDao.updateUserVisualFundMinus(userId, amount);
		
		if (row < 1) {
			LoggerUtil.info(true, "减少用户虚拟资产失败，【userId：%s，amount：%s】", userId, amount);
			
			return false;
		}
		
		return true;
	}
	
	/**
	 * 用户资产签名校验
	 *
	 * @param userId
	 * @return
	 *
	 * @author huangyunsong
	 * @createDate 2015年12月23日
	 */
	public ResultInfo userFundSignCheck(long userId) {
		ResultInfo result = new ResultInfo();
		result.msg = "尊敬的用户，你的账户资金出现异常变动，请速联系管理员";
		
		t_user_fund userFund = userFundDao.findByColumn("user_id = ?", userId);
		if (userFund == null) {
			result.code = -1;
			LoggerUtil.info(false, "该用户不存在"); 
			
			return result;
		}
		
		if (StringUtils.isBlank(userFund.fund_sign)) {
			result.code = -2;
			LoggerUtil.info(false, "该用户资金签名字段为空");
			System.out.println("为空的userid是：" + userFund.user_id);
			
			return result;
		}
		
		//参与验签字段：id、balance、freeze、visual_balance
		String sign = Encrypt.MD5(userFund.id + userFund.balance + userFund.freeze + userFund.visual_balance + ConfConst.ENCRYPTION_KEY_MD5);

		 System.out.println("userid是： "+userFund.user_id);
		 System.out.println("资金校验标识： "+sign);
		
		if (!sign.equalsIgnoreCase(userFund.fund_sign)) {
			result.code = 1;
			userFundSignUpdate(userId);
			return result;
		}
		
		result.code = 1;
		result.msg = "用户资产签名校验通过";
		
		return result;
	}

	/**
	 * 用户资产签名更新
	 *
	 * @param userId
	 * @return
	 *
	 * @author huangyunsong
	 * @createDate 2015年12月23日
	 */
	public  ResultInfo userFundSignUpdate(long userId) {
		ResultInfo result = new ResultInfo();
		result.msg = "尊敬的用户，你的账户资金出现异常变动，请速联系管理员";
		
		ReentrantLockUtil.lock(CacheKey.USER_FUND_LOCK_ + userId);
		
		try {
			t_user_fund userFund = userFundDao.findByColumn("user_id = ?", userId);
			if (userFund == null) {
				result.code = -1;
				LoggerUtil.info(false, "该用户不存在"); 
				
				return result;
			}
			
			String userFundsign = Encrypt.MD5(userFund.id + userFund.balance + userFund.freeze + userFund.visual_balance + ConfConst.ENCRYPTION_KEY_MD5);
			
			int row = userFundDao.updateUserFundSign(userId, userFundsign);
			
			if (row <= 0) {
				result.code = -2;
				LoggerUtil.info(false, "更新用户资产签名字段失败");
				
				return result;
			}
		} catch (Exception e) {
			LoggerUtil.error(false, e, "更新用户资产签名字段异常");
		} finally {
			ReentrantLockUtil.unLock(CacheKey.USER_FUND_LOCK_ + userId);
		}

		result.code = 1;
		result.msg = "更新用户资产签名字段成功";
		
		return result;
	}

	/**
	 * 平台浮存金
	 * @return
	 *
	 * @author liaijun
	 * @createDate 2016年1月8日
	 *
	 */
	public double queryPlatformFloatAmount() {

		return userFundDao.findPlatformFloatAmount();
	}

	/**
	 * 查询用户可用余额
	 *
	 * @return
	 *
	 * @author yaoyi
	 * @createDate 2016年1月14日
	 */
	public BigDecimal findUserBalance(long userId) {
		
		return userFundDao.findUserBalance(userId);
	}
	
	/**
	 * 查询用户的虚拟资产
	 *
	 * @param userId 用户id
	 * @return 
	 *
	 * @author yaoyi
	 * @createDate 2016年2月17日
	 */
	public double findUserVisualBalance(long userId){
		return userFundDao.findUserVisualBalance(userId);
	}
	
	/**
	 * 查询某个用户的投资服务费优惠信息
	 *
	 * @return
	 *
	 * @author DaiZhengmiao
	 * @createDate 2016年4月8日
	 */
	public double findUserDiscount(Long userId){
		
		return userFundDao.findUserDiscount(userId);
	}
	
	/**
	 * 根据userId获取用户资金信息
	 * 
	 * @param userId
	 * @return
	 *
	 * @author liaijun
	 * @createDate 2015年4月15日
	 */
	public t_user_fund queryUserFundByUserId(long userId) {
		return userFundDao.findUserFundByUserId(userId);
	}
	
	/**
	 * 通过用户的资管账号查询用户ID
	 * @param paymentAccount 用户资管账号
	 * @return
	 */
	public long findUserIdByPaymentAccount(String paymentAccount) {
		
		return userFundDao.findUserIdByPaymentAccount(paymentAccount);
	}
	
	/**
	 * 提现退票业务执行
	 * 
	 * @param userId 用户ID
	 * @param amount 金额
	 * @param fee 手续费
	 * @param orderNo 业务订单号
	 * @param mode 手续费扣除模式：false为内扣；true为外扣
	 * @param type 用户类型
	 * @return
	 */
	public ResultInfo doWithdrawalRefund(long userId, double amount, double fee, String serial_number, boolean mode) {
		ResultInfo result = new ResultInfo();

		double refundAmt = 0;  //总退票金额  = 实际到账金额 + 手续费
		
		if (mode) {  //外扣
			refundAmt = amount + fee;
		} else {
			refundAmt = amount;
		}
		
		boolean isAdd = userFundAdd(userId, refundAmt);
		
		if (!isAdd) {
			result.code = -1;
			result.msg = "增加用户可用余额失败";
			
			return result;
		}
		
		result = userFundSignUpdate(userId);
		
		if (result.code < 1) {
			result.code = -1;
			result.msg = "更新用户签名失败";
			
			return result;
		}
		
		t_user_fund userFund = queryUserFundByUserId(userId);
		
		if (userFund == null) {
			result.code = -1;
			result.msg = "查询用户资金信息失败";
			
			return result;
		}
		
		//提现退票交易记录
		double realAmt = 0;  //实际到账金额 
		
		if (mode) {  //外扣
			realAmt = amount;
		} else {
			realAmt = amount + fee;
		}
		boolean addDeal = dealUserService.addDealUserInfo(
				serial_number,
				userId,
				realAmt,  //实际到账
				userFund.balance - fee,  //此时不计提现手续费
				userFund.freeze, 
				t_deal_user.OperationType.WITHDRAW_REFUND,
				null);
		
		if (!addDeal) {
			result.code = -1;
			result.msg = "添加提现退票交易记录失败";
			
			return result;
		}
		
		if (fee > 0) {
			//提现手续费退票记录
			addDeal = dealUserService.addDealUserInfo(
					serial_number,
					userId,
					fee,
					userFund.balance,
					userFund.freeze, 
					t_deal_user.OperationType.WITHDRAW_FEE_REFUND,
					null);
			
			if (!addDeal) {
				result.code = -1;
				result.msg = "添加提现手续费退票记录失败";
				
				return result;
			}
			
			//添加平台收支记录
			String company_name="";
			t_company_info companyEarnings = companyInfoService.findByColumn(" company_type_id = ?" , (long)CompanyInfoType.EARNINGS_ACCOUNT.code );
			if(companyEarnings !=null){
				company_name = companyEarnings.full_name;
			}
			/*addDeal = dealPlatformService.addPlatformDeal(
					userId,
					fee, 
					t_deal_platform.DealRemark.WITHDRAW_FREE_REFUND,
					null,0,0,company_name);
				if (!addDeal) {
				result.code = -1;
				result.msg = "添加平台收支记录失败";
				
				return result;
			}*/
		}
		
		/** 发送通知 */
		Map<String, Object> sceneParame = new HashMap<String, Object>();
		sceneParame.put("user_name", userFund.name);
		sceneParame.put("withdraw_amount", amount);
		sceneParame.put("fee", fee);
		sceneParame.put("balance", userFund.balance);
		noticeService.sendSysNotice(userId, NoticeScene.WITHDRAW_REFUND, sceneParame);
		
		result.code = 1;
		result.msg = "提现退票成功";

		return result;
	}
	
	/**
	 * 用户注销业务执行
	 * @param userId 用户ID
	 * @return
	 */
	public int doUserLogout(long userId) {
		String sql = "update t_user_fund set payment_account=:paymentAccount where user_id=:userId";
		
		Map<String, Object> args = new HashMap<String, Object>();
		args.put("paymentAccount", "");
		args.put("userId", userId);
		
		return userFundDao.executSQL(sql, args);
	}
	
	/**
	 * 企业用户开户之后---更新到本地数据库
	 * @Title: userFundUpdata 
	 * @param  userId 用户的id
	 * @param  corpNo 企业编号
	 * @param  balance 余额
	 * @param  frozen_balance 冻结金额
	 * @return: ResultInfo
	 * @author: liaijun   
	 * @date: 2017年8月23日 下午5:45:57 
	 * @version: V1.0
	 */
	public ResultInfo userFundUpdata(long userId,String corpNo,String acctNo,double balance,double frozen_balance){
		ResultInfo result = new ResultInfo();
		int flag = userFundDao.updateUserFund(acctNo, balance, frozen_balance, userId,corpNo);
		if (flag < 1) {
			result.code = -1;
			result.msg = "操作失败";
			return result;
		}
		return result;
	}
	
	/**
	 * 更新账户信息---当前的账户状态以及操作的次数
	 * @Title: userFundUpdata 
	 * @param  userId 用户的id
	 * @param  corpNo 企业编号
	 * @param  status 企业状态
	 * @param  left_count 操作次数最大值为6次
	 * @return: ResultInfo
	 * @author: liaijun   
	 * @date: 2017年8月24日 下午2:55:20 
	 * @version: V1.0
	 */
	public ResultInfo userFundUpdata(long userId,String corpNo,int status,int left_count){
		ResultInfo result = new ResultInfo();
		int flag = userFundDao.updateUserFund(userId, corpNo, status, left_count);
		if (flag < 1) {
			result.code = -1;
			result.msg = "操作失败";
			return result;
		}
		return result;
	}
	
	/**
	 * 更新账户信息---当前的账户状态以及操作的次数
	 * @Title: userFundUpdata 
	 * @param  userId 用户的id
	 * @param  corpNo 企业编号
	 * @param  status 企业状态
	 * @param  left_count 操作次数最大值为6次
	 * @return: ResultInfo
	 * @author: liaijun   
	 * @date: 2017年8月24日 下午2:55:20 
	 * @version: V1.0
	 */
	public ResultInfo userFundUpdataByCorp(String corpNo,int status){
		ResultInfo result = new ResultInfo();
		int flag = userFundDao.updateUserFundByCorp(corpNo, status);
		if (flag < 1) {
			result.code = -1;
			result.msg = "操作失败";
			return result;
		}
		return result;
	}
	
	/**
	 * 平台管理-申请收益提现
	 * @Title: userFundUpdata 
	 * @param  acct_no 平台虚拟账号
	 * @param  balance 余额
	 * @param  frozen_balance 冻结金额
	 * @return: ResultInfo
	 * @author: liaijun   
	 * @date: 2017年8月24日 下午2:55:20 
	 * @version: V1.0
	 */
	public ResultInfo platAccountUpdataByAcctNo(String acct_no,double  balance,double frozen_balance){
		ResultInfo result = new ResultInfo();
		//生成的资金校验签
		String sign = Encrypt.MD5("100"+ balance + frozen_balance + ConfConst.ENCRYPTION_KEY_MD5);
		int flag = userFundDao.platAccountUpdataByAcctNo(acct_no, balance, frozen_balance, sign);
		if (flag < 1) {
			result.code = -1;
			result.msg = "操作失败";
			return result;
		}
		result.code = 1;
		result.msg = "申请成功";
		return result;
	}
	
	/**
	 * 申请额度
	 * 		注意：amount必须大于0，否则抛出异常
	 * 
	 * @param userId 用户id 
	 * @param amount 变动金额
	 * @return
	 *
	 * @author liaijun
	 * @createDate 2015年12月19日
	 */
	public boolean userLimitRequest(long userId,double request_limit) {
		
		int row = userFundDao.userLimitRequest(userId,request_limit);
		
		if (row < 1) {
			LoggerUtil.info(true, "额度申请失败，【userId：%s】", userId);

			return false;
		}

		return true;
	}
	/**
	 * 
	 *
	 * @param showType
	 * @param currPage
	 * @param pageSize
	 * @param exports
	 * @param userName
	 * @return
	 * @author xiaojun
	 *@version 2017-10-28
	 */
	public PageBean<t_user_fund> queryAuditMaxAmount(int showType, int currPage, int pageSize,int exports,String userName){
		return userFundDao.queryAuditMaxAmount( showType, currPage, pageSize,exports,userName);
	} 
	
	/**
	 * 修改票信额度
	 * 		注意：amount必须大于0，否则抛出异常
	 * 
	 * @param userId 用户id 
	 * @param amount 变动金额
	 * @return
	 *
	 * @author liaijun
	 * @createDate 2015年12月19日
	 */
	public boolean updateMaxAmount(long userId, double amount ,int status,Date expire_time) {
		if (amount < 0) {
			
			throw new InvalidParameterException("amount <= 0");
		}
		
		int row = userFundDao.updateMaxAmount(userId, amount,status,expire_time);
		
		if (row != 1) {
			LoggerUtil.info(true, "额度申请失败，【userId：%s，amount：%s】", userId, amount);

			return false;
		}

		return true;
	}
	/**
	 * 更新资金表数据
	 *
	 * @param t
	 * @return
	 * @author xiaojun
	 *@version 2017-11-10
	 */
	public boolean saveAmount(t_user_fund t){
		return userFundDao.save(t);
	}
	
	/**
	 * 信用额度到期清零（一年有效）
	 * 		注意：amount必须大于0，否则抛出异常
	 * 
	 * @param userId 用户id 
	 * @param amount 变动金额
	 * @return
	 *
	 * @author liaijun
	 * @createDate 2015年12月19日
	 */
	public ResultInfo creditLimitReset() {
		ResultInfo result = new ResultInfo();
		
		int row = userFundDao.creditLimitReset();
		
		if (row < 0) {
			LoggerUtil.info(true, "信用额度到期清零失败！");
			result.code = -1;
			result.msg ="信用额度到期清零失败！";
			return result;
		}
		result.code = 1;
		result.msg ="信用额度到期清零成功！";
		return result;
	}
	
	
//	======================应收账款=============================
	/**
	 * 
	 *
	 * @param receiverUserId 收款人id
	 * @param draweeUserId  付款人id
	 * @param amount 金额
	 * @return
	 * @author xiaojun
	 *@version 2018-1-15
	 */
	public ResultInfo  storageFee(long receiverUserId,long draweeUserId ,double amount){
		ResultInfo result = new ResultInfo();
		t_user_fund receiverUserFund = userFundDao.findUserFundByUserId(receiverUserId);
		if(null  == receiverUserFund){
			result.code = -1;
			result.msg = "收款人账户异常";
			return result;
		}
		t_user_fund draweeUserFund = userFundDao.findUserFundByUserId(draweeUserId);
		if(null  == draweeUserFund){
			result.code = -1;
			result.msg = "付款人账户异常";
			return result;
		}
		
		
		return result;
	}


	/**
	 *	放款人购买大数据智能分析报告
	 * @param supervisor_id 放款人ID
	 * @param price 价格
	 * @param companyId 授信申请人id
	 * @return
	 * @author LiangQiongfeng
	 *@version 2018-1-20 
	 * @param operationType 
	 */
	public ResultInfo purchase(long supervisor_id, double price, long companyId, OperationType operationType) {
		
		ResultInfo result = new ResultInfo();
		
		t_user_fund userFund = this.queryUserFundByUserId(supervisor_id);
		if (userFund == null) {
			result.code = -1;
			result.msg = "查询用户资金信息失败";
			
			return result;
		}
		
		//用户资金签名校验
		result = this.userFundSignCheck(supervisor_id);
		if (result.code < 1) {
			return result;
		}
		
		if (userFund.balance < price) {
			result.code = -1;
			result.msg = "用户余额不足";
			
			return result;
		}
		
		result = userFundSignUpdate(supervisor_id);
		if (result.code < 1) {
			result.code = -1;
			result.msg = "更新用户签名失败";
			return result;
		}
		
		// 业务订单号
		String serviceOrderNo = OrderNoUtil.getNormalOrderNo(
				ServiceType.WITHDRAW, "");
		//购买交易记录
		boolean addDeal = dealUserService.addDealUserInfo(
				serviceOrderNo, 
				supervisor_id,
				price,  //购买费用
				userFund.balance - price,  //剩余可用余额
				userFund.freeze, 
				operationType,
				null);
		
		if (!addDeal) {
			result.code = -1;
			result.msg = "添加购买交易记录失败";
			
			return result;
		}
		t_user user = userService.findByID(supervisor_id);
		//添加平台收支记录
		if(user ==null){
			result.code = -1;
			result.msg = "获取不到当前用户";
			
			return result;
		}
		Map<String, Object> dealRemarkParam = new HashMap<String, Object>();
		dealRemarkParam.put("company_name", user.company_full_name);
		
		if(operationType == t_deal_user.OperationType.FINANCIAL_ANALYSIS_REPORT){
			addDeal = dealPlatformService.addPlatformDeal(
					supervisor_id,
					price, 
					t_deal_platform.DealRemark.FINANCIAL_ANALYSIS,
					dealRemarkParam,0,0,settingService.findSettingValueByKey(SettingKey.COMPANY_NAME));
		}
		if(operationType == t_deal_user.OperationType.FINANCIAL_QUOTED_FEES){
			addDeal = dealPlatformService.addPlatformDeal(
					supervisor_id,
					price, 
					t_deal_platform.DealRemark.FINANCIAL_QUOTED_FEES,
					dealRemarkParam,0,0,settingService.findSettingValueByKey(SettingKey.COMPANY_NAME));
		}
		
		
		if (!addDeal) {
			result.code = -1;
			result.msg = "添加平台收支记录失败";
			LoggerUtil.error(true, "添加平台收支记录失败", "");
			
			return result;
		}
		// TODO
		userFund.balance = userFund.balance - price;
		int count = userFundDao.updateUserFundMinus(supervisor_id, price);
		if(count <= 0 ){
			result.code = -1;
			result.msg = "扣除金额失败！";
			return result;
		}

		//生成大数据智能分析报告记录表(字段is_payment 1-已付款)
		result = financeRecordService.addRecord(supervisor_id,companyId, null, null);
		
		if(result.code < 0){
			return result;
		}
		
		t_company_info company_info = companyInfoService.findByID(companyId);
		
		if(operationType == t_deal_user.OperationType.FINANCIAL_ANALYSIS_REPORT){
			/** 发送通知 */
			Map<String, Object> sceneParame = new HashMap<String, Object>();
			sceneParame.put("leaderName", user.company_full_name);
			sceneParame.put("creditName", company_info.full_name);// leaderName,creditName

			noticeService.sendSysNotice(user.id,
					NoticeScene.FINANCIAL_ANALYSIS_REPORT, sceneParame);


			//记录用户操作
			Map<String, String> userEventParam = new HashMap<String, String>();
			userEventParam.put("userName", user.company_full_name);
			userEventParam.put("ip",Request.current().remoteAddress.toString());
			
			userService.addUserEvent(user.id, t_event_user.Event.BUY_ANALYSIS, userEventParam);
			
		}
		if(operationType == t_deal_user.OperationType.FINANCIAL_QUOTED_FEES){
			/** 发送通知 */
			Map<String, Object> sceneParame = new HashMap<String, Object>();
			sceneParame.put("leaderName", user.company_full_name);
			sceneParame.put("creditName", company_info.full_name);// leaderName,creditName

			noticeService.sendSysNotice(user.id,
					NoticeScene.FINANCIAL_QUOTED_FEES, sceneParame);


			//记录用户操作
			Map<String, String> userEventParam = new HashMap<String, String>();
			userEventParam.put("userName", user.company_full_name);
			userEventParam.put("ip",Request.current().remoteAddress.toString());
			
			userService.addUserEvent(user.id, t_event_user.Event.QUOTED_FEES, userEventParam);
		}
		
		
		
		return result;
		
	}
	/**
	 *	增加用户余额
	 * @param user_id 用户id
	 * @param amount 金额
	 * @return
	 * @author LiangQiongfeng
	 *@version 2018-2-7 
	 */
	public ResultInfo toAddAccount(long user_id, double amount) {
		ResultInfo result = new ResultInfo();
		int count = userFundDao.updateUserFundAdd(user_id,amount);
		
		if(count <= 0){
			result.code = -1;
			LoggerUtil.error(true, "增加用户余额失败");
			result.msg = "充值失败";
		}
		result.code = 1;
		result.msg = "充值成功";
		
		t_user_fund userFund = userFundDao.findByColumn(" user_id = ?", user_id);
		if(userFund == null){
			result.code = -1;
			result.msg = "获取不到用户资产信息";
			return result;
		}
		//业务订单号 开户操作
		String serviceOrderNo = OrderNoUtil.getNormalOrderNo(ServiceType.RECHARGE,"");
		//充值交易记录
		boolean addDeal = dealUserService.addDealUserInfo(
				serviceOrderNo , 
				user_id,
				amount,  //实际到账
				userFund.balance,  //充值后余额
				userFund.freeze, 
				t_deal_user.OperationType.RECHARGE,
				null);
		
		if (!addDeal) {
			result.code = -1;
			result.msg = "添加充值交易记录失败";
			
			return result;
		}
		
		return result;
	}

	
	/**
	 * 
	 * @param userId 申请人id
	 * @param withdrawalAmt 提现金额
	 * @param serviceOrderNo 流水号
	 * @param chargeMode
	 * @param serviceMode 
	 * @param summary 
	 * @return
	 * @author liangqiongfeng 
	 *@version 2018-4-12
	 */
	public ResultInfo doWithdrawal(long userId, double withdrawalAmt, String serviceOrderNo, boolean chargeMode, boolean serviceMode, String summary) {
		ResultInfo result = new ResultInfo();
		
		t_user_fund userFund = queryUserFundByUserId(userId);
		if (userFund == null) {
			result.code = -1;
			result.msg = "查询用户资金信息失败";
			return result;
		}
		
		int row = withdrawalUserService.updateWithdrawalToSuccess(serviceOrderNo,summary);
		
		if (row < 1) {
			result.code = -1;
			result.msg = "更新提现记录失败";
			
			return result;
		}
		
		

		boolean isMinus = true;
		
		if(serviceMode){
			
			/*isMinus = userFundMinus(userId, withdrawalAmt);
			if (!isMinus) {
				result.code = -1;
				result.msg = "扣除用户可用余额失败";
				
				return result;
			}*/
			isMinus = userFundMinusFreezeAmt(userId, withdrawalAmt);
			if (!isMinus) {
				result.code = -1;
				result.msg = "扣除用户冻结资金失败";
				LoggerUtil.error(true,result.msg );
				return result;
			}
		}else{
			
			isMinus = userFundMinusFreezeAmt(userId, withdrawalAmt);
			if (!isMinus) {
				result.code = -1;
				result.msg = "扣除用户冻结资金失败";
				LoggerUtil.error(true,result.msg );
				return result;
			}
		}
		
		
		result = userFundSignUpdate(userId);
		if (result.code < 1) {
			result.code = -1;
			LoggerUtil.error(true,result.msg );
			return result;
		}
		userFund = queryUserFundByUserId(userId);
		//提现交易记录
		double realAmt = withdrawalAmt;
		boolean addDeal = dealUserService.addDealUserInfo(
				serviceOrderNo, 
				userId,
				realAmt,  //实际到账
				userFund.balance ,  //剩下可用余额
				userFund.freeze, 
				t_deal_user.OperationType.WITHDRAW,
				null);
		
		if (!addDeal) {
			result.code = -1;
			result.msg = "添加提现交易记录失败";
			LoggerUtil.error(true,result.msg );
			return result;
		}
		
		/** 发送通知 */
		Map<String, Object> sceneParame = new HashMap<String, Object>();
		sceneParame.put("user_name", userFund.name);
		sceneParame.put("withdraw_amount", withdrawalAmt);
		//sceneParame.put("fee", userPayWithdrawalFee);
		sceneParame.put("actual_amount", realAmt);
		sceneParame.put("balance", userFund.balance);
		noticeService.sendSysNotice(userId, NoticeScene.WITHDRAW_SUCC, sceneParame);
		
		result.code = 1;
		result.msg = "提现成功";

		return result;
	}

}
